#include "stm32_power.h"
#include "stm32_uart.h"


/* 该函数由CubeMX根据时钟树生成，函数原型位于main.c中 */
extern void SystemClock_Config(void);


/**
  * @brief  进入低功耗模式
  * @param  LPMode: 选择具体的低功耗模式
  * @retval 无
  */
void STM32_PWR_Enter_LowPowerMode(uint8_t LPMode, uint8_t DebugMode)
{
	switch (LPMode)
	{
		case PWR_FULL_MODE:
			STM32_PWR_Enter_FullRunMode();
		  break;
    
    case PWR_LPRUN_MODE:
			STM32_PWR_Enter_LPRunMode();
		  break;
        
    case PWR_SLEEP_MODE:
			STM32_PWR_Enter_SleepMode();
		  break;
    
    case PWR_LPSLEEP_MODE:
			STM32_PWR_Enter_LPSleepMode();
		  break;
            
    case PWR_STOP0_MODE:
			STM32_PWR_Enter_StopMode(PWR_STOP0_MODE, DebugMode);
		  break;
			
		case PWR_STOP1_MODE:
			STM32_PWR_Enter_StopMode(PWR_STOP1_MODE, DebugMode);
		  break;
		
		case PWR_STOP2_MODE:
			STM32_PWR_Enter_StopMode(PWR_STOP2_MODE, DebugMode);
		  break;
		
		case PWR_STANDBY_MODE:
			STM32_PWR_Enter_StandbyMode();
		  break;
			
    case PWR_SHUTDOWN_MODE:
			STM32_PWR_Enter_ShutdownMode();
		  break;
    
		default:
		  break;
	}
}



void STM32_PWR_Enter_StopMode(uint8_t StopMode, uint8_t DebugMode)
{
  __HAL_UART_ENABLE_IT(&hlpuart1, UART_IT_RXNE);
  
  __HAL_UART_CLEAR_FLAG(&hlpuart1, UART_FLAG_RXNE);
  
  HAL_UARTEx_EnableStopMode(&hlpuart1);
	
  if (DebugMode == DEBUG_MODE_DISABLE)
  {
    
    HAL_DBGMCU_DisableDBGStopMode();
  }
  else
  {
    HAL_DBGMCU_EnableDBGStopMode();
  }
  
	/* 外部有源晶振禁止 */
//	HAL_GPIO_WritePin(EN_PWR_TXCO_GPIO_Port, EN_PWR_TXCO_Pin, GPIO_PIN_RESET);
	
	switch (StopMode)
	{
		case PWR_STOP0_MODE:
			STM32_PWR_Enter_Stop0Mode();
			break;
		case PWR_STOP1_MODE:
			STM32_PWR_Enter_Stop1Mode();
			break;
		case PWR_STOP2_MODE:
			STM32_PWR_Enter_Stop2Mode();
			break;
		default:
			break;
	}
	
	/* 外部有源晶振使能 */
//	HAL_GPIO_WritePin(EN_PWR_TXCO_GPIO_Port, EN_PWR_TXCO_Pin, GPIO_PIN_SET);
	
	/* 重新配置系统时钟 */
	STM32_RCC_SystemClock_Internal();
}


void STM32_PWR_Enter_FullRunMode(void)
{
  
}


void STM32_PWR_Enter_LPRunMode(void)
{
  
}


void STM32_PWR_Enter_SleepMode(void)
{
	/*Suspend Tick increment to prevent wakeup by Systick interrupt. 
		Otherwise the Systick interrupt will wake up the device within 1ms (HAL time base)*/
  HAL_SuspendTick();

  /* Enter Sleep Mode , wake up is done once jumper is put between PA.12 (Arduino D2) and GND */
  HAL_PWR_EnterSLEEPMode(PWR_MAINREGULATOR_ON, PWR_SLEEPENTRY_WFI);

  /* Resume Tick interrupt if disabled prior to SLEEP mode entry */
  HAL_ResumeTick();
}


void STM32_PWR_Enter_LPSleepMode(void)
{
	/*Suspend Tick increment to prevent wakeup by Systick interrupt. 
		Otherwise the Systick interrupt will wake up the device within 1ms (HAL time base)*/
  HAL_SuspendTick();

  /* Enter Sleep Mode , wake up is done once jumper is put between PA.12 (Arduino D2) and GND */
  HAL_PWR_EnterSLEEPMode(PWR_MAINREGULATOR_ON, PWR_SLEEPENTRY_WFI);

  /* Resume Tick interrupt if disabled prior to SLEEP mode entry */
  HAL_ResumeTick();
}


void STM32_PWR_Enter_Stop0Mode(void)
{
  HAL_PWREx_EnterSTOP0Mode(PWR_STOPENTRY_WFI);
}


void STM32_PWR_Enter_Stop1Mode(void)
{
  HAL_PWREx_EnterSTOP1Mode(PWR_STOPENTRY_WFI);
}


void STM32_PWR_Enter_Stop2Mode(void)
{
  LL_C2_PWR_SetPowerMode(LL_PWR_MODE_STOP2);
  
  HAL_PWREx_EnterSTOP2Mode(PWR_STOPENTRY_WFI);
}


void STM32_PWR_Enter_StandbyMode(void)
{
  HAL_PWR_EnterSTANDBYMode();
}


void STM32_PWR_Enter_ShutdownMode(void)
{
  HAL_PWREx_EnterSHUTDOWNMode();
}


void STM32_RCC_SystemClock_Internal(void)
{
  SystemClock_Config();
}


void STM32_RCC_SystemClock_External(void)
{
  
}





